﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Permissions;
using jQuery;

namespace jQuery.WebControls.UI
{
    /// <summary>
    /// Control web que aplica distintos Effects de animación a distintos controles de una página.
    /// </summary>
    [AspNetHostingPermission(SecurityAction.Demand,
    Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand,
    Level = AspNetHostingPermissionLevel.Minimal),
    DefaultProperty("Controles")]
    [ToolboxData("<{0}:ControlFx runat=server></{0}:ControlFx>")]
    public class ControlFx : WebControl
    {
        private ClientScriptProxy scriptManager;
        private List<jQueryEffect> controles;
        private jQueryScriptManager jQueryMngr;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!Page.IsPostBack)
            {
                if (!DesignMode)
                    CheckQueryManager();
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if ((EjecutarEffectsSiempre || (!EjecutarEffectsSiempre && !Page.IsPostBack))
                 && Controles.Count > 0)
            {
                jQueryEffect aux;
                string clientId; ;
                string clientIdToTransfer;

                if (ConcatenarEffects)
                {
                    jQueryEffect auxNext;
                    for (int i = 0; i < Controles.Count - 1; i++)
                    {
                        aux = (jQueryEffect)Controles[i];
                        auxNext = (jQueryEffect)Controles[i + 1];

                        if (aux.IdControlToTransfer != string.Empty)
                            clientIdToTransfer = getClientId(Controles[i].IdControlToTransfer);
                        else
                            clientIdToTransfer = "";

                        clientId = getClientId(Controles[i].IdControl);
                        aux.CallBackJavaScriptFunction = auxNext.JavaScriptFunction;
                        
                        aux.AutoExecute = i == 0 ? true : false;
                        
                        if (i == 0)
                        {
                            ClientScriptProxy.RegisterStartupScript(this, typeof(ControlFx), "", aux.ExecuteEffectsOnWindowLoad(clientId, clientIdToTransfer), true);
                            //aux.EjecutarEfectoOnWindowLoad(clientId, clientIdToTransfer).RenderControl(output);
                        }
                        else
                        {
                            ClientScriptProxy.RegisterStartupScript(this, typeof(ControlFx), "", aux.ExecuteEffect(clientId, clientIdToTransfer), true);
                            //aux.EjecutarEfecto(clientId, clientIdToTransfer, false).RenderControl(output);
                        }
                    }

                    auxNext = Controles[Controles.Count - 1];
                    if (auxNext.IdControlToTransfer != string.Empty)
                        clientIdToTransfer = getClientId(auxNext.IdControlToTransfer);
                    else
                        clientIdToTransfer = "";

                    clientId = getClientId(auxNext.IdControl);
                    //ClientScriptProxy.RegisterStartupScript(this, typeof(ControlFx), auxNext.ExecuteEffect(clientId, clientIdToTransfer, false).InnerText, "", true);
                    ClientScriptProxy.RegisterClientScriptBlock(Page, GetType(), "executeEffect", auxNext.ExecuteEffect(clientId, clientIdToTransfer), true);
                }
                else
                {
                    for (int i = 0; i < Controles.Count; i++)
                    {
                        aux = (jQueryEffect)Controles[i];

                        if (aux.IdControlToTransfer != string.Empty)
                            clientIdToTransfer = getClientId(Controles[i].IdControlToTransfer);
                        else
                            clientIdToTransfer = "";

                        clientId = getClientId(Controles[i].IdControl);
                        //ClientScriptProxy.RegisterStartupScript(this, typeof(ControlFx), aux.ExecuteEffect(clientId, clientIdToTransfer, true).InnerText, "", true);
                        ClientScriptProxy.RegisterClientScriptBlock(Page, GetType(), String.Format("executeEffect{0}", i), aux.ExecuteEffect(clientId, clientIdToTransfer), true);
                    }
                }
            }            
        }

        #region PROPERTIES
        /// <summary>
        /// Control collection to apply the jquery effects
        /// </summary>
        [Category("Data")]
        [Description("List of object with the server control ides and client control ides to apply the effects")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public List<jQueryEffect> Controles
        {
            get
            {
                if (controles == null)
                {
                    controles = new List<jQueryEffect>();
                }
                return controles;
            }
        }

        /// <summary>
        /// Gets or sets whether the effects must be executed one after another or independently      
        /// </summary>
        [Category("Appareance")]
        [DefaultValue("false")]
        [Description("Gets or sets whether the effects must be executed one after another or independently")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]        
        public bool ConcatenarEffects
        {
            get
            {
                if (ViewState["ce"] == null)
                {
                    ViewState.Add("ce", false);
                }
                return bool.Parse(ViewState["ce"].ToString());
            }
            set
            {
                ViewState["ce"] = value;
            }
        }

        /// <summary>
        /// Gets or sets if the effect must be execute always when the page is reloaded, or just when it's executed for the firsts
        /// time, it means when Page.IsPostBack is false
        /// </summary>
        [Category("Appareance")]
        [DefaultValue(false)]
        [Description("Gets or sets if the effect must be execute always when the page is reloaded, or just when it's executed for the firsts time, it means when Page.IsPostBack is false")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public bool EjecutarEffectsSiempre
        {
            get
            {
                if (ViewState["ees"] == null)
                {
                    ViewState.Add("ees", false);
                }
                return bool.Parse(ViewState["ees"].ToString());
            }
            set
            {
                ViewState["ees"] = value;
            }
        }

        private ClientScriptProxy ClientScriptProxy
        {
            get
            {
                if (scriptManager == null)
                {
                    scriptManager = ClientScriptProxy.Current;
                }
                return scriptManager;
            }
        }


        private jQueryScriptManager jQueryManager
        {
            get
            {
                if (jQueryMngr == null)
                    jQueryMngr = Common.Instance.Get_jQueryScriptManager(Page);
                return jQueryMngr;
            }
        }
        #endregion

        /// <summary>
        /// Determines if the control idetificador belongs to a server control at either the Page or MasterPage. In that case, returns the ClientID of control, but returns the last parameter id_control
        /// </summary>
        /// <param name="id_control">Object ID</param>
        /// <returns>Returns the control client id</returns>
        private string getClientId(string id_control)
        {
            object o = null;
            if (Page.Master != null)
            {
                if (Page.Master.FindControl(id_control) != null)
                {
                    o = Page.Master.FindControl(id_control);
                }                
            }
            if (o == null && Page.FindControl(id_control) != null)
            {
                o = Page.FindControl(id_control);
            }
            
            if (o != null)
            {
                if (o.GetType().ToString().IndexOf("WebControl") >= 0)
                {
                    WebControl wc = o as WebControl;
                    return wc.ClientID;
                }              
                else if (o.GetType().ToString().IndexOf("HtmlControl") >= 0)
                {
                    System.Web.UI.HtmlControls.HtmlControl wc = o as System.Web.UI.HtmlControls.HtmlControl;
                    return wc.ClientID;
                }
                else
                {
                    throw new Exception(String.Format(jQuery.Messages.CFX_err1, o.GetType().ToString()));                    
                }                
            }           
            else
            {
                return id_control;
            }
        }

        private void CheckQueryManager()
        {
            Common.Instance.CheckJQueryScriptManager(Page);
        }
    }
}
